数据与方法

📒当一个vue实例被创建时,它向vue响应式系统中加入了其data能找到的所有的属性,当这些属性值变化时,视图将会响应。
是创建的时候才会去监听,数据才是响应式的。如果在创建之后向一个对象中添加一个属性,这个属性不会被监听到,不是响应式的。在创建对象的时候,如果能预计有什么属性,应该先初始化对象,设置一些初始值。
📒 Object.freeze()会冻结一个对像,阻止修改现有的对象。如果使用了和这个方法,页面不会再监听这个对象了。
📒 不要在选项属性或者回调函数上使用箭头函数。箭头函数是和父级上下文绑定的,this在所有的生命周期中,不一定是指向vue实例。
📒 v-once: 一次性的绑定值,当数据改变的时候,不会再随之变化了,
📒 在模板中放入太多的逻辑会让模板过重且难以维护。对于复杂的逻辑,不推荐放在模版里面,应该使用计算属性

计算属性&&方法&&watch

📒 计算属性是基于依赖来进行缓存的。只有在相关的依赖发生变化的时候才会重新计算。方法其实可以得到和计算属性相同的结果。
不同的是,计算属性在依赖没有变化的时候,不会更新,有缓存。

📒 缓存的意义:如果有个结果计算会消耗大量的性能才能计算出来,如果使用函数,那每次调用这个结果都要执行一次函数,性能消耗打,使用
计算属性,在其中依赖没有变化的时候不会重新计算,性能消耗比较小
📒 watch:当需要在数据变化时执行异步或者开销比较大的操作使用

📒 在写代码的时候,如果某个结果依赖一个值的变化,并且计算这个结果比较复杂,推荐使用计算属性。要善用计算属性。

class && style

📒 尽量不要写在模版里面,模版应该是简洁的。

<div v-bind:class="classObject"></div>
data: {
  isActive: true,
  error: null
},
computed: {
  classObject: function () {
    return {
      active: this.isActive && !this.error,
      'text-danger': this.error && this.error.type === 'fatal'
    }
  }
}

v-if && v-show

  • v-if:有很高的切换开销,在运行切换少的情况下推荐使用
  • v-show: 初始渲染开销高, 在频繁切换的时候推荐使用

📒 v-if和v-for一起使用的时候,v-for优先级比v-if高

v-for

📒 可以通过一个对象来迭代,第二个参数为键名,第三个参数为索引

<div v-for="(value, key, index) in object">
  {{index}}{{ key }}: {{ value }}
</div>

new Vue({
  el: '#v-for-object',
  data: {
    object: {
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    }
  }
})

📒 “就地复用”策略:
当 Vue.js 用 v-for 正在更新已渲染过的元素列表时,它默认用“就地复用”策略。如果数据项的顺序被改变,Vue 将不会移动 DOM 元素来匹配数据项的顺序, 而是简单复用此处每个元素,并且确保它在特定索引下显示已被渲染过的每个元素。这个类似 Vue 1.x 的 track-by="$index" 。
📒 v-for可以使用方法:可以用来过滤处理数据了

<li v-for="n in even(numbers)">{{ n }}</li>
data: {
  numbers: [ 1, 2, 3, 4, 5 ]
},
methods: {
  even: function (numbers) {
    return numbers.filter(function (number) {
      return number % 2 === 0
    })
  }
}

key

作用:主要是为了高效的更新虚拟DOM。提高遍历性能。另外vue中在使用相同标签名元素的过渡切换时,也会使用到key属性,其目的也是为了让vue可以区分它们,否则vue只会替换其内部属性而不会触发过渡效果。

  1. 两个相同的组件产生类似的DOM结构,不同的组件产生不同的DOM结构。
  2. 同一层级的一组节点,他们可以通过唯一的id进行区分。

当页面的数据发生变化时,Diff算法只会比较同一层级的节点:如果节点类型不同,直接干掉前面的节点,再创建并插入新的节点,不会再比较这个节点以后的子节点了。如果节点类型相同,则会重新设置该节点的属性,从而实现节点的更新。当某一层有很多相同的节点时,也就是列表节点时,Diff算法的更新过程默认情况下也是遵循以上原则。

数组更新检测

以下变异方法可以触发视图更新

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

⚠️ 以下几种方法不能检测数组变化:

  • 当你利用索引直接设置一个项时,例如:
vm.items[indexOfItem] = newValue
  • 当你修改数组的长度时,例如:
vm.items.length = newLength

解决方法:

Vue.set(vm.items, indexOfItem, newValue)
vm.items.splice(indexOfItem, 1, newValue)

📒 vue不能检测对象属性的添加或者删除
解决方法:

  • 通过vue.set
  • 使用Object.assgin或者_.extends(),创建新对象

事件处理

📒 在方法中传入$event,可以访问DOM原生事件对象

<button v-on:click="warn($event)">
  Submit
</button>

📒 事件修饰符

表单输入绑定

📒 v-model不会在输入法组合文字过程中更新,可以使用input来监听这个过程。
📒修饰符:

  • .lazy: v-model内容change的时候更新,而不是input的时候更新
  • .number
  • .trim

组件

📒 动态组件:通过is绑定组件名称, 有些标签里面只能使用固定标签,不能直接写组件名称,可以通过is来使用组件

<!-- 组件会在 `currentTabComponent` 改变时改变 -->
<component v-bind:is="currentTabComponent"></component>

<table>
  <tr is="blog-post-row"></tr>
</table>

📒 全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生

props

📒 props是通过引用传入的,所以子组件修改会影响父组件的变化
📒 prop 会在一个组件实例创建之前进行验证 (beforeCreated)
📒 interitAttrs
在版本 2.4 之前,默认情况下父作用域的不被作为props特性绑定的属性,将会作为普通的 HTML 属性,应用在跟元素上。设置 interitAttrs 为 false,之后,不会应用到跟元素上。

// parent.vue
<template>
  <child-commpent :foo="f" :boo="b"></child-comment>
</template>
<script>
const childComment = () => import('./childCom.vue')
export default {
  data () {
    return {
      f: 'Hello world!'
      b: 'Hello Vue!'
    }  
  }
}
// childComment.vue
<template>
  <div>{{ foo }}<div>
</template>

<script>
export default {
  props: ['foo']
}
</script>
</script>

最后会被渲染城这样:

<div boo="Hello Vue!">Hello world!</div>

设置 interitAttrs 为 false

export default {
  props: ['foo'],
  interitAttrs: false
}

渲染结果:

<div>Hello world!</div>

📒 $attrs
使用 v-bind="$attrs", 将父组件中不被认为 props特性绑定的属性传入子组件中,通常配合 interitAttrs 选项一起使用

<template>
  <child-commpent :foo="f" :boo="b" coo="c"></child-comment>
</template>
<script>
const childComment = () => import('./childCom.vue')
export default {
  data () {
    return {
      f: 'Hello world!'
      b: 'Hello Vue!',
      c: 'Hello'
    }  
  }
}
</script>
// childComment.vue
<template>
  <div>{{ foo }}<div>
  <p>attrs: {{ $attrs }}</p>
</template>
<script>
export default {
  props: ['foo'],
  interitAttrs: false
}
</script>

渲染结果:

Hello world!
Hello Vue!, Hello

📒 props可以以字符串数组的形式列出

自定义的v-model

边界处理情况

📒 $refs 只会在组件渲染完成之后生效,并且它们不是响应式的。这只意味着一个直接的子组件封装的“逃生舱”——你应该避免在模板或计算属性中访问 $refs。

keep-alive

📒 keep-alive组件可以记住包含组件的状态

nextTick

在修改数据之后立即调用这个函数,可以获取更新后的DOM,如果需要DOM更新后进行一些操作,可以使用这个函数

mixins

数据的优先级比组件内部定义的低
同名钩子函数混合成一个数组,混入对象的钩子比组件内部定义的钩子先执行

渲染函数&& jsx

虚拟DOM更新页面节点

vue不能检测对象属性的添加和删除,可以通过vue.set(obj, key, value)来添加属性

.sync

提供对于 prop 的双向绑定。

  <child :bar.sync="foo"></child>

其实是个语法糖

  <child :bar="foo" @update:bar="e => foo = e">

此时需要在子组件中显示触发事件:

  this.$emit('update:bar', newValue)

获取表单数据

获取同时还可以给变量一个初始值

const { userName, password, checked = [] } = this.form

template && render

当Vue选项对象中有render渲染函数时,Vue构造函数将直接使用渲染函数渲染DOM树,
当选项对象中没有render渲染函数时,Vue构造函数首先通过将template模板生成render函数,然后再渲染DOM树,
而当选项对象中既没有render渲染函数,也没有template模板时,会通过el属性获取挂载元素的outerHTML来作为模板,并编译生成渲染函数。
如果 Vue 选项中包含渲染函数,该模板将被忽略。
Vue 选项中的 render 函数若存在,则 Vue 构造函数不会从 template 选项或通过 el 选项指定的挂载元素中提取出的 HTML 模板编译渲染函数。
进行DOM渲染的时候,render函数优先级最高,template和el次之。最终得到的都是render函数
在实例挂载之后,元素可以用vm.$el访问

未完。。。


oylp
365 声望17 粉丝

只是一个普普通通喜欢吃脂肪还长肉的人